<template>
  <el-select v-model.trim="currentValue" :multiple="multiple" :disabled="disabled" :value-key="valueKey" :size="size"
    :clearable="clearable" :collapse-tags="collapseTags" :multiple-limit="multipleLimit" :name="name"
    :autocomplete="autocomplete" :placeholder="placeholder" :filterable="filterable" :allow-create="allowCreate"
    :filter-method="filterMethod" :remote="remote" :remote-method="remoteMethod" :loading="loading"
    :loading-text="loadingText" :no-match-text="noMatchText" :no-data-text="noDataText" :popper-class="popperClass"
    :reserve-keyword="reserveKeyword" :default-first-option="defaultFirstOption"
    :popper-append-to-body="popperAppendToBody" :automatic-dropdown="automaticDropdown" v-bind="$attrs"
    @update:modelValue="handleInputEvent">
    <el-option v-for="item in options" :key="item[model.value]" :label="item[model.label]" :value="item[model.value]" />
  </el-select>
</template>

<script lang="ts">
import { defineComponent, PropType, computed, ref, watch } from "vue";

interface OptionItem {
  [key: string]: any;
  disabled?: boolean;
}

interface ModelConfig {
  label: string;
  value: string;
  data?: string;
}

export default defineComponent({
  name: "Select",
  inheritAttrs: false,
  props: {
    modelValue: {
      type: [String, Number, Boolean, Object, Array] as PropType<
        string | number | boolean | object | any[]
      >,
      default: "",
    },
    options: {
      type: Array as PropType<OptionItem[]>,
      default: () => [],
    },
    model: {
      type: Object as PropType<ModelConfig>,
      default: null,
    },
    multiple: {
      type: Boolean,
      default: false,
    },
    disabled: {
      type: Boolean,
      default: false,
    },
    valueKey: {
      type: String,
      default: "",
    },
    size: {
      type: String as PropType<"large" | "default" | "small">,
      default: "default",
    },
    clearable: {
      type: Boolean,
      default: false,
    },
    collapseTags: {
      type: Boolean,
      default: false,
    },
    multipleLimit: {
      type: Number,
      default: 0,
    },
    name: {
      type: String,
      default: "",
    },
    autocomplete: {
      type: String,
      default: "off",
    },
    placeholder: {
      type: String,
      default: "请选择",
    },
    filterable: {
      type: Boolean,
      default: false,
    },
    allowCreate: {
      type: Boolean,
      default: false,
    },
    filterMethod: {
      type: Function as PropType<(_query: string) => void>,
      default: null,
    },
    remote: {
      type: Boolean,
      default: false,
    },
    remoteMethod: {
      type: Function as PropType<(_query: string) => void>,
      default: null,
    },
    loading: {
      type: Boolean,
      default: false,
    },
    loadingText: {
      type: String,
      default: "加载中",
    },
    noMatchText: {
      type: String,
      default: "无匹配数据",
    },
    noDataText: {
      type: String,
      default: "无数据",
    },
    popperClass: {
      type: String,
      default: "",
    },
    reserveKeyword: {
      type: Boolean,
      default: false,
    },
    defaultFirstOption: {
      type: Boolean,
      default: false,
    },
    popperAppendToBody: {
      type: Boolean,
      default: true,
    },
    automaticDropdown: {
      type: Boolean,
      default: false,
    },
  },
  emits: ["update:modelValue"],
  setup(props, { emit }) {
    const currentValue = ref(props.modelValue);

    const model = computed(() => {
      if (props.model) {
        return {
          label: props.model.label,
          value: props.model.value,
          data: props.model.data || "data",
        };
      }
      return { label: "label", value: "value", data: "data" };
    });

    watch(
      () => props.modelValue,
      (val) => {
        currentValue.value = val;
      }
    );

    const handleInputEvent = (value: any) => {
      emit("update:modelValue", value);
    };

    return {
      currentValue,
      model,
      handleInputEvent,
    };
  },
});
</script>
